#pragma once

#include <algorithm>
#include <cmath>
#include <string>

class CodeSqStrings
{
public:
    static std::string code( const std::string & strng );
    static std::string decode( const std::string & strng );
};

std::string CodeSqStrings::code( const std::string & strng )
{
    const size_t max = std::ceil( std::sqrt( strng.size() ) );
    std::string result( max * max + max - 1, 11 );

    // map string
    size_t x, y;

    for( size_t pos = 0; pos < strng.size(); ++pos ) {
        x = max - 1 - pos / max;
        y = pos % max;
        result[x + y * ( max + 1 )] = strng[pos];
    }

    // new line symbos
    for( size_t pos = max; pos < max * max + max - 1; pos += max + 1 ) {
        result[pos] = '\n';
    }

    return result;
}

std::string CodeSqStrings::decode( const std::string & strng )
{
    const size_t max = std::floor( std::sqrt( strng.size() ) );
    std::string result( strng.size(), 11 );

    // map string
    size_t x, y;
    size_t count = 0;

    for( size_t pos = 0; pos < strng.size(); ++pos ) {
        if( strng[pos] == 11 || strng[pos] == '\n' ) {
            continue;
        }

        x = pos / ( max + 1 );
        y = max - 1 - pos % ( max + 1 );
        result[x + y * max] = strng[pos];
        count++;
    }

    // shrink size
    result.resize( count );

    return result;
}
